<template>
  <el-image
    v-bind="$attrs"
    :src="isVisible? $attrs.src : placeholder"
    v-on="$listeners"
  >
    <template #error>
      <slot name="error">
        <div class="loading-error">
          <div class="spinner"></div>
          <span>图片加载失败</span>
        </div>
      </slot>
    </template>
    <template #placeholder>
      <slot name="placeholder">
        <div class="loading">
          <div class="spinner"></div>
          <div style="margin-top: 10px;">加载中...</div>
        </div>
      </slot>
    </template>
    <!-- 遍历子组件非作用域插槽，并对父组件暴露 -->
    <template v-for="(index, name) in $slots" v-slot:[name]>
      <slot :name="name" />
    </template>
    <!-- 遍历子组件作用域插槽，并对父组件暴露 -->
    <template v-for="(index, name) in $scopedSlots" v-slot:[name]="data">
      <slot :name="name" v-bind="data"></slot>
    </template>
  </el-image>
</template>

<script>
export default {
  name: 'LazyLoadImage',
  inheritAttrs: false,
  props: {
    placeholder: {
      type: String,
      default: ''
    }
  },
  data() {
    return {
      isVisible: false
    };
  },
  mounted() {
    const observer = new IntersectionObserver((entries, observer) => {
      entries.forEach(entry => {
        if (entry.isIntersecting) {
          this.isVisible = true;
          observer.unobserve(entry.target);
        }
      });
    });
    observer.observe(this.$el);
  }
};
</script>

<style scoped>
/* 加载中样式 */
.loading {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 100%;
  width: 100%;
}

/* 加载失败样式 */
.loading-error {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 100%;
  width: 100%;
  color: red;
}

/* 转圈图标样式 */
.spinner {
  border: 4px solid rgba(0, 0, 0, 0.1);
  border-left-color: #000;
  border-radius: 50%;
  width: 28px;
  height: 28px;
  animation: spin 1s linear infinite;
  margin-bottom: 8px;
}

@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}
</style>
